package com.starbaba.loanbusiness.view;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.base.common.database.BaseDao;
import com.base.common.database.DaoHelper;
import com.base.common.database.EasyTransaction;
import com.base.common.log.LogService;
import com.base.common.util.StringUtils;
import com.google.gson.JsonObject;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.starbaba.core.utils.PropertyParamMapBuilder;
import com.starbaba.core.utils.Struts2Utils;
import com.starbaba.core.utils.json.JsonUtils;
import com.starbaba.core.web.constant.WebConstants;
import com.starbaba.core.web.page.PageResponse;
import com.starbaba.core.web.struts2.BaseAction;
import com.starbaba.loanbusiness.model.LoanBusinessModel;
import com.starbaba.loanbusiness.model.LoanBusinessTempModel;
import com.starbaba.loanbusiness.service.LoanBusinessService;
import com.starbaba.loanbusiness.service.impl.LoanBusinessServiceImpl;
import com.starbaba.model.dictionary.Constant;
import com.starbaba.statistics.utils.StatisticsUtils;
import com.starbaba.system.user.model.UserVO;
import com.starbaba.util.ExcelOperateUtil;
import com.starbaba.utils.DateUtils;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class LoanBusinessAction extends BaseAction implements ModelDriven<LoanBusinessModel> {

	private static final long serialVersionUID = 1L;
	
	private File upload;
	private String savePath;
	private String uploadFileName;
	private String uploadContentType;

	private String fileName;
	private InputStream input;

	private LoanBusinessModel model;

	@SuppressWarnings("deprecation")
	private final BaseDao dao = new BaseDao(Constant.POOL_LIFE);
	private LoanBusinessService service = new LoanBusinessServiceImpl();
	private HttpSession session = ServletActionContext.getRequest().getSession();
	private static final String LOAN_BUSINESS_LIST_TEMP = "loan_business_list_temp_";
	private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
	private UserVO userVO = (UserVO) session.getAttribute(WebConstants.SESSION_ATTRIBUTE_USER);
	

	/**
	 * 查询
	 * @throws Exception 
	 */
	public void getLoanBusinessList() throws Exception {

		parsePageRequest();
		paramsMap = PropertyParamMapBuilder.buildFromHttpRequest(Struts2Utils.getRequest(), paramsMap);
        
		List list = new ArrayList();
		PageResponse pageResponse = new PageResponse();
		int start = pageRequest.getIDisplayStart();
		int length = pageRequest.getIDisplayLength();
		
		HttpSession session = ServletActionContext.getRequest().getSession();
		paramsMap.put("userName", ((UserVO)session.getAttribute(WebConstants.SESSION_ATTRIBUTE_USER)).getUsername());		
		paramsMap.put("isManager", String.valueOf(((UserVO)session.getAttribute(WebConstants.SESSION_ATTRIBUTE_USER)).getIsManager()));
				
		String dateformat = (String) paramsMap.get("dateformat");

		if ("0".equals(dateformat)) { // 日模式
			list = service.getDataList(start, length, pageResponse, paramsMap);
		} else if ("1".equals(dateformat)) { // 周模式
			list = service.getWeekDataList(start, length, pageResponse, paramsMap);
		} else if ("2".equals(dateformat)) { // 月模式
			list = service.getMonthDataList(start, length, pageResponse, paramsMap);
		}
		
		pageResponse.setAaData(list);
		pageResponse.setSEcho(pageRequest.getSEcho());
		try {
			sendJsonMessage(JsonUtils.toJson(pageResponse, null, true, null, false));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 上传数据
	 * 
	 * @return
	 * @throws Exception
	 */
	public void uploadExcelData() throws Exception {

		parsePageRequest();
		paramsMap = PropertyParamMapBuilder.buildFromHttpRequest(Struts2Utils.getRequest(), paramsMap);
		
		int totalNums = 0;
		List<LoanBusinessTempModel> resultList = new ArrayList<LoanBusinessTempModel>();
		
		try {
			File file = upload;
			String fileSuffix = (String) paramsMap.get("suffix");
			
			if (file.exists()) {
				String fileName = file.getAbsolutePath();
				// 临时文件后缀名改为源文件后缀名
				fileName = fileName.replace(".tmp", "." + fileSuffix.toLowerCase());
				file.renameTo(new File(fileName));
				file = new File(fileName);
			}

			ExcelOperateUtil poi = new ExcelOperateUtil();
			String[][] result = poi.getData(file);

			int rows = 1; // Excel表格的第几行
			
			for (String[] row : result) {
				if (rows == 1) {
					rows++;
					continue;
				}
				String startDate = row[0]; // 开始时间
				String endDate = row[1]; // 结束时间
				String sourceId = row[2]; // 合作方ID
				String type = row[4]; // 所属类型
				String productId = row[6]; // 产品Id
				String register = row[8]; // 注册数
				String apply = row[9]; // 申请数
				String in_success = row[10]; // 进件成功数
				String money_count = row[11]; // 出额数
				String total_amount = row[12]; // 总出额金额
				String settle_amount = row[13]; // 结算金额

				if (StringUtils.isEmpty(startDate)) {
					continue;
				}

				if (StringUtils.isEmpty(endDate)) {
					continue;
				}

				if (StringUtils.isEmpty(sourceId)) {
					continue;
				}

				if (StringUtils.isEmpty(type)) {
					continue;
				}

				// 计算时间间隔
				List<Date> list = DateUtils.getDatesBetweenTwoDate(format.parse(startDate), format.parse(endDate));

				int nums = list.size();
				totalNums = totalNums + nums;

				for (int i = 0; i < list.size(); i++) {
					
					LoanBusinessTempModel busi = new LoanBusinessTempModel();
					busi.setSource_id(Long.parseLong(sourceId));
					busi.setType(Integer.parseInt(type));
					busi.setRegister((int) Integer.parseInt(register) / nums);
					busi.setApply((int) Integer.parseInt(apply) / nums);
					busi.setSuccess((int) Integer.parseInt(in_success) / nums);
					busi.setMoney_count((int) Integer.parseInt(money_count) / nums);
					busi.setTotal_amount(String.valueOf(Double.parseDouble(total_amount) / nums));
					busi.setSettle_amount(String.valueOf(Double.parseDouble(settle_amount) / nums));
					busi.setOperator(userVO.getUsername());
					busi.setCsv_date(format.format(list.get(i)));
					busi.setPrdid(productId);
					rows++;
					resultList.add(busi);
				}
			}
			saveToDB(resultList, null, 0);
			JsonObject resultJson = new JsonObject();
			resultJson.addProperty("total", totalNums);
			resultJson.addProperty("success", resultList.size());
			session.setAttribute(LOAN_BUSINESS_LIST_TEMP + userVO.getUserid(), resultList);
			sendJsonMessage(resultJson.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void saveToDB(final List<LoanBusinessTempModel> templist, final List<LoanBusinessModel> list, Integer type) {

		try {
			long startTime = System.currentTimeMillis();
			DaoHelper.excuteTransaction(new EasyTransaction() {
				@Override
				public <T> T excute(Object... arg0) throws Exception {

					List<Object[]> paramsReList = new ArrayList<Object[]>();
					List<Object[]> paramsAddList = new ArrayList<Object[]>();
					
					if (type == 0) {
						for (LoanBusinessTempModel model : templist) {

							List<Object> params = new ArrayList<Object>();
							params.add(model.getSource_id());
							params.add(model.getType());
							params.add(model.getPrdid());
							params.add(model.getCsv_date());
							paramsReList.add(params.toArray());

							List<Object> addparams = new ArrayList<Object>();

							addparams.add(model.getSource_id());
							addparams.add(model.getType());
							addparams.add(model.getRegister());
							addparams.add(model.getApply());
							addparams.add(model.getSuccess());
							addparams.add(model.getMoney_count());
							double totalAmount = Double.parseDouble(model.getTotal_amount());
							double settleAmount = Double.parseDouble(model.getSettle_amount());
							addparams.add(StatisticsUtils.formatNumbers(totalAmount, 4, 0));
							addparams.add(StatisticsUtils.formatNumbers(settleAmount, 4, 0));
							addparams.add(model.getOperator());
							addparams.add(model.getCsv_date());
							addparams.add(model.getPrdid());
							paramsAddList.add(addparams.toArray());
						}
						try {
							dao.excuteBatch("delete from loan_api_import_record_temp where source_id = ? and type = ? " 
						            + "and prdid = ? and csv_date = ?", paramsReList);
							dao.excuteBatch("insert into loan_api_import_record_temp (source_id, type, register, apply, success, money_count,"
									+ "total_amount,settle_amount, operator,csv_date, prdid) values(?,?,?,?,?,?,?,?,?,?,?)", paramsAddList);
						} catch (Exception e) {
							LogService.error(e);
						}
					} else {
						for (LoanBusinessModel model : list) {

							List<Object> params = new ArrayList<Object>();
							params.add(model.getSource_id());
							params.add(model.getType());
							params.add(model.getPrdid());
							params.add(model.getCsv_date());
							paramsReList.add(params.toArray());

							List<Object> addparams = new ArrayList<Object>();

							addparams.add(model.getSource_id());
							addparams.add(model.getType());
							addparams.add(model.getRegister());
							addparams.add(model.getApply());
							addparams.add(model.getSuccess());
							addparams.add(model.getMoney_count());
							double totalAmount = Double.parseDouble(model.getTotal_amount());
							double settleAmount = Double.parseDouble(model.getSettle_amount());
							addparams.add(StatisticsUtils.formatNumbers(totalAmount, 4, 0));
							addparams.add(StatisticsUtils.formatNumbers(settleAmount, 4, 0));
							addparams.add(model.getOperator());
							addparams.add(model.getCsv_date());
							addparams.add(model.getPrdid());
							paramsAddList.add(addparams.toArray());
						}
						try {
							dao.excuteBatch("delete from loan_api_import_record where source_id = ? and type = ? " 
						            + "and prdid = ? and csv_date = ?", paramsReList);
							dao.excuteBatch("insert into loan_api_import_record (source_id, type, register, apply, success, money_count,"
									+ "total_amount,settle_amount, operator,csv_date, prdid) values(?,?,?,?,?,?,?,?,?,?,?)", paramsAddList);

							// 上传成功删除TEMP数据
							dao.excuteBatch("delete from loan_api_import_record_temp where source_id = ? and type = ? " 
							        + "and prdid = ? and csv_date = ?", paramsReList);
						} catch (Exception e) {
							LogService.error(e);
						}
					}
					return null;
				}
			});
			long endTime = System.currentTimeMillis();
			LogService.info("商务数据录入成功!，共耗时:" + (endTime - startTime) + "ms");
		} catch (Exception e) {
			e.printStackTrace();
			LogService.error("getGenerldata", e);
		}
	}
	
	
	/**
	 * 确认上传
	 * 
	 * @return
	 * @throws Exception
	 */
	public void confirmUpload() throws Exception {

		try {
			List<LoanBusinessTempModel> resultList = (List<LoanBusinessTempModel>) 
					session.getAttribute(LOAN_BUSINESS_LIST_TEMP + userVO.getUserid());
            
			List<LoanBusinessModel> dataList = new ArrayList<LoanBusinessModel>();
			
			for (LoanBusinessTempModel model : resultList) {

				long sourceId = model.getSource_id();
				int type = model.getType();
				String productId = model.getPrdid();
				String csvDate = model.getCsv_date();

				LoanBusinessModel businessModel = new LoanBusinessModel();
				businessModel.setSource_id(sourceId);
				businessModel.setType(type);
				businessModel.setPrdid(productId);
				businessModel.setCsv_date(csvDate);

				LoanBusinessModel busi = new LoanBusinessModel(model.getSource_id(), type, model.getRegister(), model.getApply(), model.getSuccess(), model.getMoney_count(),
						model.getTotal_amount(), model.getSettle_amount(), model.getOperator(), model.getCsv_date(), productId);
				dataList.add(busi);
			}
			saveToDB(null, dataList, 2);
			JsonObject resultJson = new JsonObject();
			resultJson.addProperty("success", dataList.size());
			resultJson.addProperty("total", resultList.size());
			session.removeAttribute(LOAN_BUSINESS_LIST_TEMP + userVO.getUserid());
			sendJsonMessage(resultJson.toString());
		} catch (Exception e) {
			LogService.error(e);
		}
	}
	
	/**
	 * 导出CSV
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws ParseException 
	 */
	public String exportDetailCSV() throws UnsupportedEncodingException, ParseException {

		parsePageRequest();
		PageResponse pageResponse = new PageResponse();
		paramsMap = PropertyParamMapBuilder.buildFromHttpRequest(Struts2Utils.getRequest(), paramsMap);

		pageRequest.setIDisplayStart(-1);
		pageRequest.setIDisplayLength(-1);
		pageRequest.setOrderby("createtime");
		pageRequest.setOrder("desc");

		int start = pageRequest.getIDisplayStart();
		int length = pageRequest.getIDisplayLength();
		
		HttpSession session = ServletActionContext.getRequest().getSession();
		paramsMap.put("userName", ((UserVO)session.getAttribute(WebConstants.SESSION_ATTRIBUTE_USER)).getUsername());
		paramsMap.put("isManager", String.valueOf(((UserVO)session.getAttribute(WebConstants.SESSION_ATTRIBUTE_USER)).getIsManager()));

		String dateformat = (String) paramsMap.get("dateformat");
		List<LoanBusinessModel> list = new ArrayList<LoanBusinessModel>();

		if ("0".equals(dateformat)) { // 日模式
			list = (List<LoanBusinessModel>) service.getDataList(start, length, pageResponse, paramsMap);
		} else if ("1".equals(dateformat)) { // 周模式
			list = service.getWeekDataList(start, length, pageResponse, paramsMap);
		} else if ("2".equals(dateformat)) { // 月模式
			list = service.getMonthDataList(start, length, pageResponse, paramsMap);
		}
		
		String value = service.exportLoanDataList(list);
		input = new ByteArrayInputStream(value.getBytes("GBK"));
		fileName = System.currentTimeMillis() + ".csv";
		return ActionSupport.SUCCESS;
	}
	

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public InputStream getInput() {
		return input;
	}

	public void setInput(InputStream input) {
		this.input = input;
	}

	@Override
	public LoanBusinessModel getModel() {
		if (model == null) {
			model = new LoanBusinessModel();
		}
		return model;
	}
}
